﻿using System.Drawing;
using System.Text;
using Basic.WxApiRemoteModel.WxMini.Model;
using Basic.WxApiService.ApiInterface;
using Basic.WxApiService.WxModel;
using Basic.WxApiService.WxModel.Mini;
using WeDonekRpc.Client.Attr;
using WeDonekRpc.Helper;

namespace Basic.WxApiService.WxMiniApi
{
    [ClassLifetimeAttr(ClassLifetimeType.SingleInstance)]
    internal class MiniApi : BaseMiniApi, IMiniApi
    {
        private const string _GetUserEncryptKey = "https://api.weixin.qq.com/wxa/business/getuserencryptkey";
        private const string _CheckSession = "https://api.weixin.qq.com/wxa/checksession";
        private const string _CheckEncryptedMsg = "https://api.weixin.qq.com/wxa/business/checkencryptedmsg";
        private const string _GetUnlimitedQRCode = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";
        private const string _GetUserPhoneNumber = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";

        public MiniEncryptKey[] GetEncryptKey (WxMerToken token, string openId, string signature)
        {
            StringBuilder json = new StringBuilder("{");
            _ = json.AppendFormat("\"openid\":\"{0}\",\"signature\":\"{1}\",\"sig_method\":\"hmac_sha256\"", openId, signature);
            _ = json.Append('}');
            MiniEncryptKeyResult res = PostJson<MiniEncryptKeyResult>(_GetUserEncryptKey, token, json.ToString());
            return res.key_info_list;
        }
        public MiniUserPhone GetUserPhone (WxMerToken token, string code)
        {
            MiniUserPhoneResult res = PostJson<MiniUserPhoneResult>(_GetUserPhoneNumber, token, "{\"code\":\"" + code + "\"}");
            return res.phone_info;
        }
        public byte[] CreateQr (WxMerToken token, QrCreateParam param)
        {
            StringBuilder json = new StringBuilder("{");
            _ = json.AppendFormat("\"page\":\"{0}\",\"width\":{1},\"is_hyaline\":{2},\"env_version\":\"{3}\",\"scene\":\"{4}\",\"check_path\":{5}", param.Page, param.Width, param.IsHyaline ? "true" : "false", param.EnvVersion.ToString(), param.Scene, param.CheckPath ? "true" : "false");
            if (param.LineColor.HasValue)
            {
                _ = json.Append(",\"auto_color\":false,\"line_color\":{");
                Color color = param.LineColor.Value;
                _ = json.AppendFormat("\"r\":{0},\"b\":{1},\"g\":{2}", color.R, color.B, color.G);
                _ = json.Append('}');
            }
            else
            {
                _ = json.Append(",\"auto_color\":true");
            }
            _ = json.Append('}');
            return PostJsonByStream(_GetUnlimitedQRCode, token, json.ToString());
        }
        public bool CheckEncrypted (WxMerToken token, string data)
        {
            CheckEncryptedRes res = PostJson<CheckEncryptedRes>(_CheckEncryptedMsg, token, "{\"encrypted_msg_hash\":\"" + data + "\"}");
            return res.vaild;
        }

        public bool CheckSession (WxMerToken token, string openId, string signature)
        {
            string query = string.Format("openid={0}&signature={1}&sig_method=hmac_sha256", openId, signature);
            WxBasicRes res = GetResult<WxBasicRes>(_CheckSession, token, query);
            if (res.errcode == 0)
            {
                return true;
            }
            else if (res.errcode == 87009)
            {
                return false;
            }
            throw new ErrorException(string.Concat("wx.mini.api.", res.errcode));
        }
    }
}
